import { createUseStyles } from "react-jss";
import { isUndefined } from "@ct0/functions";
import { ThemeContext } from "../theme";
import Add from "./components/Add";
import classNames from "classnames";
import Input from "./components/Input";
import React, { useContext, useState } from "react";
import Tag from "./components/Tag";
import TagSelect from "./components/Select";
import type { TagInputProps } from "./type";

export default TagInput;

type StyleProps = { fontSize: number };

const useStyles = createUseStyles({
  fontSize: {
    fontSize: (props: StyleProps) => props.fontSize,
  },
});

function TagInput({
  value,
  options,
  disabled,
  maxLength = 30,
  invalid,
  style,
  className,
  onChange,
  onInputChange,
  getPopupContainer,
}: TagInputProps) {
  const { fontSize } = useContext(ThemeContext);
  const classes = useStyles({ fontSize });

  const [visible, setVisible] = useState<boolean>(false);
  const [editIndex, setEditIndex] = useState<number>();

  const handleTagSelectChange = (tag: string) => {
    if (tag !== "" && !value.includes(tag)) onChange?.([...value, tag]);
    setVisible(false);
    onInputChange?.("");
  };

  const handleClose = (i: number) => {
    const result = [...value];
    result.splice(i, 1);
    onChange?.(result);
  };

  const editHandler = (e: any) => {
    if (isUndefined(editIndex)) return;
    const tag = e.target.value;
    value[editIndex] = tag;
    onChange?.([...new Set(value).values()]);
    setEditIndex(undefined);
  };

  return (
    <div
      className={classNames("ct0-tag-input", classes.fontSize, className)}
      style={style}
    >
      {value.map((x, i) => {
        if (editIndex === i) {
          return (
            <Input
              key={x}
              value={x}
              maxLength={maxLength}
              onBlur={editHandler}
              onPressEnter={editHandler}
            />
          );
        }
        return (
          <Tag
            key={x}
            disabled={disabled}
            onClose={() => handleClose(i)}
            onDoubleClick={() => setEditIndex(i)}
          >
            {x}
          </Tag>
        );
      })}
      <TagSelect
        maxLength={maxLength}
        visible={visible}
        options={options}
        onChange={handleTagSelectChange}
        onInputChange={onInputChange}
        className={classNames(
          invalid && "ct0-tag-invalid",
          !visible && "ct0-tag-trigger-hidden"
        )}
        getPopupContainer={getPopupContainer}
      />
      {!disabled && !visible && <Add onClick={() => setVisible(true)} />}
    </div>
  );
}
